<template>
  <el-upload
    ref="refUpload"
    v-model:file-list="fileList"
    :action="action"
    :headers="uploadHeaders"
    :name="props.name"
    :accept="props.accept"
    :limit="props.limit"
    :list-type="props.listType"
    :before-upload="beforeUpload"
    :on-exceed="handleExceed"
    :on-preview="handlePicturePreview"
    :on-success="handleSuccess"
    :on-remove="handleRemove"
    :="$attrs"
  >
    <slot />
    <template #trigger>
      <slot name="trigger" />
    </template>
    <template #tip>
      <slot name="tip" />
    </template>
  </el-upload>

  <el-image-viewer
    v-if="showPreview"
    :url-list="urlList"
    show-progress
    :initial-index="0"
    @close="showPreview = false"
  />
</template>

<script setup>
import { genFileId } from 'element-plus'
import { getUmsToken } from '@/utils/cookies'

const props = defineProps({
  name: {
    type: String,
    default: 'file'
  },
  url: {
    type: String,
    default: ''
  },
  accept: {
    type: String,
    default: 'image/*'
  },
  limit: {
    type: Number,
    default: 1
  },
  listType: {
    type: String,
    default: 'text'
  },
  maxSize: {
    type: Number,
    default: 1024 * 1024 * 20
  }
})

const emit = defineEmits([
  'before-upload',
  'on-exceed',
  'on-preview',
  'on-success',
  'on-remove'
])

const refUpload = ref(null)
const fileList = defineModel('fileList', {
  type: Array,
  default: () => []
})
const action = ref(import.meta.env.VITE_APP_BASE_API + '/file/upload')
const uploadHeaders = {
  Authorization: 'Bearer ' + getUmsToken(),
  lang: g_https.headersLang(),
  timeout: 10000
}
// 弹框参数
const showPreview = ref(false)
const urlList = computed(() => {
  return fileList.value.map(item => item.url)
})

const beforeUpload = file => {
  let isFile = false
  // 判断是否是规定的上传文件
  if (
    !props.accept ||
    props.accept === '*' ||
    props.accept.indexOf('/*') > -1
  ) {
    isFile = true
  } else {
    isFile = props.accept.split(',').some(item => file.name.includes(item))
  }
  // 超过最大限制
  const isLtMaxSize = file.size <= props.maxSize
  if (!isFile) {
    ElMessage.error(
      g_t('rule.uploadFileTip', {
        suffix: props.accept
      })
    )
  } else if (!isLtMaxSize) {
    ElMessage.error(
      g_t('rule.uploadSizeTip2', {
        max: g_utils.transformByteData(props.maxSize)
      })
    )
  }
  emit('before-upload', isFile && isLtMaxSize)
  return isFile && isLtMaxSize
}

const handleExceed = (files, uploadFiles) => {
  if (props.limit === 1) {
    // 清空文件列表
    refUpload.value.clearFiles()
    // 手动添加新文件到上传列表
    const file = files[0]
    file.uid = genFileId() // 生成唯一ID
    refUpload.value.handleStart(file)
    emit('on-exceed', [file], uploadFiles)
  } else {
    ElMessage.warning(
      g_t('rule.uploadNumLargeTips2', {
        limit: props.limit
      })
    )
    emit('on-exceed', files, uploadFiles)
  }
}

const handlePicturePreview = uploadFile => {
  if (urlList.value.length) showPreview.value = true
  emit('on-preview', uploadFile)
}

const handleSuccess = (res, uploadFile, uploadFiles) => {
  if (res.code === '200' && res.data) {
    ElMessage.success(res.message)
  } else {
    refUpload.value.clearFiles()
    ElMessage({
      message: res.message,
      type: 'error'
    })
  }
  emit('on-success', res, uploadFile, uploadFiles)
}

const handleRemove = (uploadFile, uploadFiles) => {
  emit('on-remove', uploadFile, uploadFiles)
}
</script>
